/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javabluetoothserial;


import app.FrameController;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;

/**
 *
 * @author isen
 */
public class JavaBluetoothSerial {
    private BufferedWriter bWriter = null;
    private BufferedReader bReader = null;
    InputStream inStream = null;
    OutputStream outStream = null;
    private StreamConnection connection;
    private StreamConnectionNotifier streamConnNotifier;
    private UUID uuid;
    private String connectionString;
    public FrameController control;
    private boolean readLoop =true;
    private boolean writingRun = true;
    private Thread readingThread;
    private Thread writingThread;
    public JavaBluetoothSerial(){
         //Create a UUID for SPP
        uuid = new UUID("1101", true);
        //Create the servicve url
        connectionString = "btspp://localhost:" + uuid +";name=Sample SPP Server";
        
    
       
       
    }

    public JavaBluetoothSerial(FrameController frameController) {
        control = frameController;
         uuid = new UUID("1101", true);
        //Create the servicve url
        connectionString = "btspp://localhost:" + uuid +";name=Sample SPP Server";
    }

    public BufferedReader getbReader() {
        return bReader;
    }

    
  public void startServer() throws IOException{
  
       
        //open server url
        streamConnNotifier = (StreamConnectionNotifier)Connector.open( connectionString );
        
        //Wait for client connection
        System.out.println("Server Started. Waiting for clients to connect...");
        connection=streamConnNotifier.acceptAndOpen();
        
        inStream=connection.openInputStream();
        outStream=connection.openOutputStream();
        
        RemoteDevice rDevice = RemoteDevice.getRemoteDevice(connection);
        System.out.println("\nconnected...");
        //System.out.println("Remote device address: "+rDevice.getBluetoothAddress());
        //System.out.println("Remote device name: "+rDevice.getFriendlyName(true));
        //System.out.println("awaiting confirmation from remote device...");
        
        
        //read string from spp client
        bReader=new BufferedReader(new InputStreamReader(inStream));
        //String lineRead=bReader.readLine();
        //System.out.println(lineRead);
        
        //send response to spp client
        
        bWriter=new BufferedWriter(new OutputStreamWriter(outStream));
        
        
        
        readInLoop();
    }
  
  public String read() throws IOException{
      String msg;
      msg = bReader.readLine();
      //System.out.println("received:"+msg);
      return msg;
  }
  
    public void write(String msg) throws IOException{
        
        bWriter.write(msg +"\n");
        //System.out.println(msg);
        bWriter.flush();
        
    }
    
   public void readInLoop(){ 
    readLoop = true;
        writingRun = true;
        this.readingThread = new Thread(){
            
            @Override
            public void run() {
                System.out.println("starting to listen");
                String incomingMsg;
                while(readLoop){
                 
                    try {
                        handleRead(read());
                       
                        
                        
                        
                        
                    } catch (IOException ex) {
                        Logger.getLogger(JavaBluetoothSerial.class.getName()).log(Level.SEVERE, null, ex);
                        
                        
                    } catch (NullPointerException ex){
                        Logger.getLogger(JavaBluetoothSerial.class.getName()).log(Level.SEVERE, null, ex);
                        return ;
                    }
                
                    
                }
            }

            private void handleRead(String read) {
                
                if(read.startsWith("slope:")){
                    try{
                    control.setSlope(Integer.parseInt(read.substring(6)));   
                    }catch (NumberFormatException ex){
                        Logger.getLogger(JavaBluetoothSerial.class.getName()).log(Level.SEVERE, null, ex);
                        
                    }
                }else if(read.startsWith("distance:")){
                    System.out.println("setting distance"+Integer.parseInt(read.substring(9)));
                    control.setDistance(Integer.parseInt(read.substring(9)));
                }else if(read.startsWith("requestData")){
                     System.out.println("App is requesting slopes and preferences");
                     control.sendSlopesData();
                     
                }else if(read.contains("reset")){
                    control.reset();
                }else if (read.startsWith("requestPreferences")){
                    control.sendPreferences();
                }else if (read.startsWith("nom:")){
                    control.writeName(read);
                    
                }
            }


           
            
        };
        
        readingThread.start();
        
   }

    
  
    public void close(){
        readLoop = false;
        try {
           if (bWriter != null ){ 
            bWriter.flush(); 
            bWriter.close();
            
           }
           if (bReader != null){
                bReader.close();
                inStream.close();
           } 
            
            } catch (IOException ex) {
                System.out.println("reader and writer were not set");
                Logger.getLogger(JavaBluetoothSerial.class.getName()).log(Level.SEVERE, null, ex);
            
            }
            
            try {
                if (connection != null)     connection.close();
                if (this.streamConnNotifier != null)     streamConnNotifier.close();
                
            } catch (IOException ex) {
                Logger.getLogger(JavaBluetoothSerial.class.getName()).log(Level.SEVERE, null, ex);
                return;
            }
            System.out.println("all pending streams and connections closed");
        
        
            }
    public static void main(String[] args) throws IOException {
        
        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println("Address: "+localDevice.getBluetoothAddress());
        System.out.println("Name: "+localDevice.getFriendlyName());
        
        JavaBluetoothSerial sampleSPPServer=new JavaBluetoothSerial();
        
        sampleSPPServer.close();
        
    }
}
